{# 模型类 、请求输入 输出模型#}
{% for import in imports %}
{{import}}
{% endfor %}
from typing import Generic, TypeVar, List, Optional
from sqlmodel import Session, SQLModel,select, func, Field
from pydantic import BaseModel
from pydantic.alias_generators import to_camel
T = TypeVar('T')
class Result(BaseModel, Generic[T]):
    success: bool = Field(..., description="是否成功")
    message: str = Field(..., description="额外消息")
    data: Optional[T] = Field(None, description="响应数据")

    @classmethod
    def ok(cls, data: T, message: str="成功"):
        return cls(data=data, message=message, success=True)

    @classmethod
    def error(cls, message: str = "失败"):
        return cls(data=None, message=message, success=False)

class PageResult(Result[T]):
    total: int = Field(0, description="数据总数")
    data: List[T] = Field(default_factory=list, description="响应数据")

    @classmethod
    def ok(cls, data: List[T], total: int, message: str = "成功"):
        return cls(data=data, total=total, message=message, success=True)

class {{table_name | to_pascal}}DTO(SQLModel):
    {% for field in dto_fields %}
    {{field}}
    {% endfor%}

class {{table_name | to_pascal}}Query({{table_name | to_pascal}}DTO):
    page_number: int = Field(1, description="页码")
    page_size: int = Field(10, description="页量")
    {% for field in query_fields %}
    {{field}}
    {% endfor%}

    def count_kwargs(self, **kwargs):
        default_exclude = {{default_exclude}}
        if v := kwargs.get("exclude"):
            default_exclude.union(v)
        data = self.model_dump(exclude=default_exclude, **kwargs)
        return data

class {{table_name|to_pascal}}({{table_name|to_pascal}}DTO, table=True):
    {% for field in do_fields %}
    {{field}}
    {% endfor%}

    @classmethod
    def create(cls, session: Session, obj_in: {{table_name|to_pascal}}DTO) -> "{{table_name|to_pascal}}":
        obj = cls(**obj_in.dict())
        session.add(obj)
        session.commit()
        session.refresh(obj)
        return obj

    @classmethod
    def query_by_id(cls, session: Session, id: int) -> Optional["{{table_name|to_pascal}}"]:
        return session.get(cls, id)

    @classmethod
    def update(cls, session: Session, id: int, obj_in: {{table_name|to_pascal}}DTO) -> Optional["{{table_name|to_pascal}}"]:
        obj = cls.query_by_id(session, id)
        if obj:
            for field, value in obj_in.dict(exclude_unset=True).items():
                setattr(obj, field, value)
            session.add(obj)
            session.commit()
            session.refresh(obj)
        return obj

    @classmethod
    def delete_by_id(cls, session: Session, id: int) -> Optional["{{table_name|to_pascal}}"]:
        obj = session.get(cls, id)
        if obj:
            session.delete(obj)
            session.commit()
        return obj

    @classmethod
    def count(cls, session: Session, **kwargs) -> int:
        return session.scalar(
  select(func.count()).
  select_from({table_name}).filter_by(**kwargs)
)

    @classmethod
    def query_all_by_limit(cls, session: Session, page_number: int, page_size: int, **kwargs) -> List["{{table_name|to_pascal}}"]:
        stmt = select(cls).filter_by(**kwargs).offset((page_number - 1) * page_size).limit(page_size)
        return session.exec(stmt).all()